<?php

class Core_Model_Permission_Account extends Dcmp_Model_Spoor {

    public function __construct() {
        parent::__construct();
    }

    protected function getTableClass() {
        return Kd_Loader::loadClass('table_permission_account');
    }

    public function getRoleIds($areaId = NULL) {
        if (!$this->hasData('role_ids')) {
            $this->data['role_ids'] = $this->getTable()->getRoleIds($this->getId(), $areaId);
        }
        return $this->data['role_ids'];
    }

    public function setRoleIds($value) {
        $this->data['role_ids'] = $value;
        return $this;
    }

    public function getRoles() {
    	$idPaths = App::getModel('permission/collection_role')
	    			->innerJoin('{t}permission_account_role', 'g', 'g.role_id', 'a.id')
	    			->eq('g.account_id', ':accountId:s')
	    			->addParameter('accountId', $this->getId())
	    			->load()
	    			->getItemPropertyValue('id_path');
	    $ids = array();
	    foreach($idPaths as $idPath){
	    	$ids = array_merge($ids, explode('_', substr($idPath, 0, -1)));
	    }	
		return App::getModel('permission/collection_role')
					->filterByIds($ids);
    }

    protected function afterInsert($transaction) {
        $this->getTable()->insertRoleRelation($this->getId(), Kd_Web::getSession()->get('managed_area_id'), $this->getRoleIds(), $transaction);
    }

    protected function afterUpdate($transaction) {
        $this->getTable()->deleteRoleRelation($this->getId(), Kd_Web::getSession()->get('managed_area_id'), $transaction);
        $this->getTable()->insertRoleRelation($this->getId(), Kd_Web::getSession()->get('managed_area_id'), $this->getRoleIds(), $transaction);
    }

    public function validate() {
        if ($this->isNew()) {
            if ($this->getTable()->checkExists(array('user_name' => $this->getUserName()))) {
                throw new Core_Model_Permission_Exception_Account(Core_Model_Permission_Exception_Account::ACCOUNT_REPEATED);
            }
        }
        return TRUE;
    }

    public function loadByUserName($userName) {
        $id = $this->getTable()->getIdByUserName($userName);
        if (!empty($id)) {
            return $this->load($id);
        }
        return $this;
    }

    public function changePassword($username, $newPassword) {
        Kd_Data_Factory::getUpdateDcl()->into('{t}permission_account')
                ->value('password', ':password:s')
                ->where()
                ->eq('user_name', ':user_name:s')
                ->closest()
                ->addParameter(array('user_name' => $username, 'password' => md5($newPassword)))
                ->execute();
    }
    
    public function assignRoad($roadId, $startTime, $endTime, $assignerId, $transaction = NULL) {
        $this->deleteRoad($roadId, $transaction);
        Kd_Data_Factory::getInsertDcl()
                ->into('{t}account_road')
                ->value('account_id', $this->getId())
                ->value('assigner_id', ':assignerId:i')
                ->value('is_assigned', 1)
                ->value('assigned_time', ':assignedTime:s')
                ->value('assign_start_time', ':assignStartTime:s')
                ->value('assign_end_time', ':assignEndTime:s')
                ->value('road_id', ':roadId:s')
                ->addParameter(array('assignerId' => $assignerId,
                    'assignedTime' => date('Y-m-d H:i:s'),
                    'assignStartTime' => $startTime,
                    'assignEndTime' => $endTime,
                    'roadId' => $roadId))
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();
        return $this;
    }

    public function deleteRoad($road, $transaction = NULL) {
        $roads = is_array($road) ? $road : array($road);
        Kd_Data_Factory::getDeleteDcl()
                ->from('{t}account_road')
                ->where()
                ->eq('account_id', ':accountId:i')
                ->contain('road_id', ':roadId:s')
                ->closest()
                ->addParameter('accountId', $this->getId())
                ->addParameter('roadId', $roads)
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();

        return $this;
    }

    public function assignIndustry($industryId, $startTime, $endTime, $assignerId, $transaction = NULL) {
        $this->deleteIndustry($industryId, $transaction);
        Kd_Data_Factory::getInsertDcl()
                ->into('{t}account_industry')
                ->value('account_id', $this->getId())
                ->value('assigner_id', ':assignerId:i')
                ->value('is_assigned', 1)
                ->value('assigned_time', ':assignedTime:s')
                ->value('assign_start_time', ':assignStartTime:s')
                ->value('assign_end_time', ':assignEndTime:s')
                ->value('industry_id', ':industryId:s')
                ->addParameter(array('assignerId' => $assignerId,
                    'assignedTime' => date('Y-m-d H:i:s'),
                    'assignStartTime' => $startTime,
                    'assignEndTime' => $endTime,
                    'industryId' => $industryId))
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();
        return $this;
    }

    public function deleteIndustry($industry, $transaction = NULL) {
        $industries = is_array($industry) ? $industry : array($industry);
        Kd_Data_Factory::getDeleteDcl()
                ->from('{t}account_industry')
                ->where()
                ->eq('account_id', ':accountId:i')
                ->contain('industry_id', ':industryId:s')
                ->closest()
                ->addParameter('accountId', $this->getId())
                ->addParameter('industryId', $industries)
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();
        return $this;
    }

    public function assignPoi($poiId, $startTime, $endTime, $assignerId, $transaction = NULL) {
        $this->deletePoi($poiId, $transaction);
        Kd_Data_Factory::getInsertDcl()
                ->into('{t}account_poi')
                ->value('account_id', $this->getId())
                ->value('assigner_id', ':assignerId:i')
                ->value('is_assigned', 1)
                ->value('assigned_time', ':assignedTime:s')
                ->value('assign_start_time', ':assignStartTime:s')
                ->value('assign_end_time', ':assignEndTime:s')
                ->value('poi_id', ':poiId:s')
                ->addParameter(array('assignerId' => $assignerId,
                    'assignedTime' => date('Y-m-d H:i:s'),
                    'assignStartTime' => $startTime,
                    'assignEndTime' => $endTime,
                    'poiId' => $poiId))
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();
        return $this;
    }

    public function deletePoi($poi, $transaction = NULL) {
        $pois = is_array($poi) ? $poi : array($poi);
        Kd_Data_Factory::getDeleteDcl()
                ->from('{t}account_poi')
                ->where()
                ->eq('account_id', ':accountId:i')
                ->contain('poi_id', ':poiId:s')
                ->closest()
                ->addParameter('accountId', $this->getId())
                ->addParameter('poiId', $pois)
                ->setDbDriver($this->getDbDriver($transaction))
                ->execute();

        return $this;
    }

    public function getIndustries() {
        return App::getModel('foundation/collection_ritu_industry')
                ->fields('a.*', 'f.industry_id', 'f.assign_start_time', 'f.assign_end_time', 'f.assigner_id', 'f.assigned_time', 'f.account_id')
                ->innerJoin('{t}account_industry', 'f', 'f.industry_id', 'a.id')
                ->eq('f.account_id', ':accountId:i')
                ->addParameter('accountId', $this->getId());
    }

    public function getRoads() {
        return App::getModel('foundation/collection_road')
                ->fields('a.*', 'f.road_id', 'f.assign_start_time', 'f.assign_end_time', 'f.assigner_id', 'f.assigned_time', 'f.account_id')
                ->innerJoin('{t}account_road', 'f', 'f.road_id', 'a.id')
                ->eq('f.account_id', ':accountId:i')
                ->addParameter('accountId', $this->getId());
    }

    public function getPois() {
        return App::getModel('foundation/collection_poi')
                ->fields('a.*', 'f.poi_id', 'f.assign_start_time', 'f.assign_end_time', 'f.assigner_id', 'f.assigned_time', 'f.account_id')
                ->innerJoin('{t}account_poi', 'f', 'f.poi_id', 'a.id')
                ->eq('f.account_id', ':accountId:i')
                ->addParameter('accountId', $this->getId());
    }

    protected function initializeTable($table) {
        $table->setName('{t}permission_account');
        $table->createColumn('id', 'integer', TRUE, TRUE);
        $table->createColumn('grade', 'string');
        $table->createColumn('user_name')->setUpdateable(FALSE);
        $table->createColumn('password')->setUpdateable(FALSE);
        $table->createColumn('status')->setDefaultValue('enabled');
        $table->createColumn('full_name', 'string');
        $table->createColumn('email', 'string');
        $table->createColumn('qq', 'string');
        $table->createColumn('birth', 'datetime');
        $table->createColumn('picture', 'string');
        $table->createColumn('address', 'string');
        $table->createColumn('is_backend', 'integer');
        parent::initializeTable($table);
    }

}